#include "Creature.h"
#include <PA9.h>       // Include for PA_Lib
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// Constructor
Creature::Creature()
{
	// Creature born with this many "lives"
	m_iLives = MAX_LIVES;
	
	/*
	// Start the creature animation.
	PA_StartSpriteAnim(UPPER_SCREEN, // screen
		SPRITE_CREATURE_00, // sprite number
		0, // first frame is 0
		3, // last frame is 3, since we have 4 frames...
		5); // Speed, set to 5 frames per second
	*/
	
	// Start creature animation	
	//PA_StartSpriteAnimEx(UPPER_SCREEN, SPRITE_CREATURE_00, 0, 3, 10, ANIM_UPDOWN);
	PA_StartSpriteAnimEx(UPPER_SCREEN, SPRITE_CREATURE_00, 0, 3, 1, ANIM_UPDOWN, -1);
		

	// Set initial radius
	m_iRadius = STARTING_RADIUS;

	// Set start position and move there
	m_iYPos = START_Y_POS;
	m_iXPos = START_X_POS;
	PA_SetSpriteXY(UPPER_SCREEN,SPRITE_CREATURE_00, m_iXPos, m_iYPos);
	
	// Frames to pass before creature is rotated
	m_iRotationDelay = 0;
	
	// The current rotation of the creature (0-511)
	m_iRotation = PA_RandMinMax(0,511);
};

// Move creature this direction
void Creature::Move(e_Direction dir, unsigned int dist)
{
	unsigned int distance = dist/(GetLivesLeft()+1);
	switch(dir)
	{
		case UP:
			if( !TOROIDAL_WRAP_ON && (m_iYPos - distance <= EDGE_TOP || m_iYPos - distance > EDGE_BOTTOM) )
			{
				m_iYPos = EDGE_TOP;
				break;
			}
			m_iYPos = m_iYPos - distance;
			if( TOROIDAL_WRAP_ON && m_iYPos <= EDGE_TOP )
			{
				m_iYPos = EDGE_BOTTOM;
			}
		break;
		case DOWN:
			if( !TOROIDAL_WRAP_ON && m_iYPos + distance > EDGE_BOTTOM )
			{
				m_iYPos = EDGE_BOTTOM;
				break;
			}
			m_iYPos = m_iYPos + distance;
			if( TOROIDAL_WRAP_ON && m_iYPos > EDGE_BOTTOM )
			{
				m_iYPos = EDGE_TOP;
			}
		break;
		case LEFT:
			if( !TOROIDAL_WRAP_ON && (m_iXPos - distance <= EDGE_LEFT || m_iXPos - distance > EDGE_RIGHT ) )
			{
				m_iXPos = EDGE_LEFT;
				break;
			}
			m_iXPos = m_iXPos - distance;
			if( TOROIDAL_WRAP_ON && m_iXPos <= EDGE_LEFT )
			{
				m_iXPos = EDGE_RIGHT;
			}
		break;
		case RIGHT:
			if( !TOROIDAL_WRAP_ON && m_iXPos + distance > EDGE_RIGHT )
			{
				m_iXPos = EDGE_RIGHT;
				break;
			}
			m_iXPos = m_iXPos + distance;
			if( TOROIDAL_WRAP_ON && m_iXPos > EDGE_RIGHT )
			{
				m_iXPos = EDGE_LEFT;
			}
		break;
		default:
		break;
	}
	PA_SetSpriteXY(UPPER_SCREEN,SPRITE_CREATURE_00, m_iXPos, m_iYPos);
};
	
// Get number of lives left
unsigned int Creature::GetLivesLeft()
{
	return m_iLives;
};

unsigned int Creature::GetMaxLives()
{
	return MAX_LIVES;
};
	
// Is creature hit at this position
bool Creature::IsHit(int x, int y)
{
	// Find distance from the hit to the center of the creature and check if it's within the creatures radius
	unsigned long length = (unsigned long)abs(x - (m_iXPos + CREATURE_SPRITE_SIZE/2));
	unsigned long height = (unsigned long)abs(y - (m_iYPos + CREATURE_SPRITE_SIZE/2));
	if( sqrt(length*length + height*height) >= (unsigned long)m_iRadius )
	{
		return false;
	}
	return true;
};

int Creature::LifeDown()
{
	if( m_iLives > 0 )
	{
		m_iLives--;
	}
	return m_iLives;
}

void Creature::LifeUp()
{
	if( m_iLives < MAX_LIVES )
	{
		m_iLives++;
	}
}
	
// Is the creature in a mid-jump/move?
bool Creature::IsMoving()
{
	return false;
};
	
// Time passes
void Creature::Tick()
{
	// Move creature if pad is pressed
	HandleMovement();
	
	if (m_iRotationDelay <= 0)
	{	
		// Calculate new rotation
		m_iRotation += PA_RandMinMax(-20,20);
		
		// Rotate creature sprites (angle, from 0 to 511)
		//PA_SetRotsetNoZoom(UPPER_SCREEN, CREATURE_ROTSET,m_iRotation);
		
		// Enforce rotation delay
		m_iRotationDelay = CREATURE_ROTATION_SPEED;
	} else {
		// Next rotation of creature sprite moves closer
		m_iRotationDelay--;
	};
	
};

// Is the powerup currently enabled (Usualy triggered by sound)
bool Creature::isPowerup()
{
	return false;
}

// Handle any movement, called by tick
void Creature::HandleMovement()
{
	if( isPowerup() )
	{
		if( Pad.Held.Up )
		{
			Move(UP, MOVE_SPEED);
		}
		else if( Pad.Held.Down )
		{
			Move(DOWN, MOVE_SPEED);
		}
		if( Pad.Held.Left )
		{
			Move(LEFT, MOVE_SPEED);
		}
		else if( Pad.Held.Right )
		{
			Move(RIGHT, MOVE_SPEED);
		}

		if( Pad.Held.X )
		{
			Move(UP, MOVE_SPEED);
		}
		else if( Pad.Held.B )
		{
			Move(DOWN, MOVE_SPEED);
		}
		if( Pad.Held.Y )
		{
			Move(LEFT, MOVE_SPEED);
		}
		else if( Pad.Held.A )
		{
			Move(RIGHT, MOVE_SPEED);
		}
	}
	else
	{
		if( Pad.Newpress.Up )
		{
			Move(UP, MOVE_STEP);
		}
		else if( Pad.Newpress.Down )
		{
			Move(DOWN, MOVE_STEP);
		}
		if( Pad.Newpress.Left )
		{
			Move(LEFT, MOVE_STEP);
		}
		else if( Pad.Newpress.Right )
		{
			Move(RIGHT, MOVE_STEP);
		}

		if( Pad.Newpress.X )
		{
			Move(UP, MOVE_STEP);
		}
		else if( Pad.Newpress.B )
		{
			Move(DOWN, MOVE_STEP);
		}
		if( Pad.Newpress.Y )
		{
			Move(LEFT, MOVE_STEP);
		}
		else if( Pad.Newpress.A )
		{
			Move(RIGHT, MOVE_STEP);
		}
	}
};

